package cn.willbj.brief.hootl.lock.demo;

import java.util.concurrent.atomic.AtomicReference;

/**
 * CAS (Compare And Set（或Compare And Swap）)
 * 		CAS是解决多线程并行情况下使用锁造成性能损耗的一种机制，CAS操作包含三个操作数——内存位置（V）、预期原值（A）、新值（B）。
 * 		如果内存位置的值与预期原值相同，那么处理器会自动将内存的值更新为新值。否则，处理器不做任何操作。无论哪种情况，处理器都会在CAS指令之前返回该位置的值。CAS有效地说明了“我认为位置V应该包含值A；如果包含该值，则将B放到这个位置；否则，不要更新该位置，只告诉我这个位置现在的值即可。”
 * 		现在几乎所有的CPU指令都支持CAS的原子操作，X86下对应的是CMPXCHG汇编指令。有了这个操作，我们就可以用其来实现各种无锁的数据结构。
 */
public class CasDemo0102 {
	
	private AtomicReference<Thread> reference = new AtomicReference<>();
	
	public void lock() {
		Thread currentThread = Thread.currentThread();
		while (!reference.compareAndSet(null, currentThread)) {
			// 自旋锁
		}
	}
	
	public void unlock() {
		Thread currentThread = Thread.currentThread();
		reference.compareAndSet(currentThread, null);
	}

public static void main(String[] args) {
		
		CasDemo0102 demo01 = new CasDemo0102();
		new Thread(new Runnable() {
			int i = 100;
			
			@Override
			public void run() {
				demo01.lock();
				
				while (i < 200) {
					i++;
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.err.println("X"+ i +": "+Thread.currentThread());
				}
				demo01.unlock();
			}
		}).start();
		
		new Thread(new Runnable() {
			int i = 0;
			@Override
			public void run() {
				demo01.lock();
				while (i < 100) {
					i++;
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("Y"+ i +": "+Thread.currentThread());
				}
				
				demo01.unlock();
			}
		}).start();
		
	}
}
